package com.baidu.process.chat.core.web.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baidu.process.chat.core.action.Actions;
import com.baidu.process.chat.core.web.bean.IMRequestServer;
import com.baidu.process.chat.core.web.bean.IMResponseResult;
import com.baidu.process.chat.core.web.service.IMService;
import com.baidu.process.chat.parser.ResultPaser;
import com.baidu.process.chat.parser.bean.QueryJsonStr;
import com.baidu.process.ngd.bean.NGDReqBody;
import com.baidu.process.ngd.bean.NGDResBody;
import com.baidu.process.ngd.bean.NGDStartResBody;
import com.baidu.process.ngd.service.NGDService;
import com.baidu.process.ngd.service.impl.NGDServiceImpl;
import com.baidu.process.record.bean.DialogueRecord;
import com.baidu.process.record.service.RecordService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import static com.baidu.process.constant.RedisKey.ImSilentNumKey;
import static com.baidu.process.constant.RedisKey.ImTimeKey;

/**
 * @Author:fangyuchao
 * @Description: 处理IM的请求报文，去请求ngd，调用解析器返回IM响应结果
 * @Date: Create in 10:16 2022/11/7
 */
@Service
public class IMServiceImpl implements IMService {
    private static final Logger logger= LoggerFactory.getLogger(IMServiceImpl.class);
    @Autowired
    private NGDService ngdService;
    @Autowired
    private ResultPaser<NGDStartResBody> firstParseNgdResult;
    @Autowired
    private ResultPaser<NGDResBody> queryParseNgdResult;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Autowired
    private RecordService recordService;


    @Override
    public IMResponseResult commonChat(IMRequestServer imRequestServer) {
        DialogueRecord dialogueRecord = new DialogueRecord();
        long startTime = System.currentTimeMillis();
        String sessionId = imRequestServer.getSessionId();
        try{
        //判断是否传入sessionid，若为空则认为是首轮进线，生成sessionid
        if (StringUtils.isEmpty(sessionId)){
            sessionId= UUID.randomUUID().toString().replace("-","");
            imRequestServer.setSessionId(sessionId);
            logger.info("首轮进线生成session:{}",sessionId);
            //重置交互时间和交互次数
            redisTemplate.opsForValue().set(ImTimeKey+sessionId,JSONObject.toJSONString(imRequestServer), 20,TimeUnit.MINUTES);
            redisTemplate.opsForValue().set(ImSilentNumKey+sessionId,"0",6,TimeUnit.HOURS);
            //解析IM请求报文
            NGDReqBody ngdReqBody = parseIMChatBody(imRequestServer);
            //请求NGD
            logger.info("[sessionId:{}]请求ngd的报文为{}",sessionId,ngdReqBody);
            NGDResBody ngdStartResBody = ngdService.query(imRequestServer,ngdReqBody);
            //调用paser解析NGD响应报文
            IMResponseResult imResponseResult = queryParseNgdResult.parseResult(ngdStartResBody,imRequestServer, dialogueRecord);
            recordService.saveAsyncRecord(dialogueRecord,imRequestServer,imResponseResult,JSONObject.toJSONString(ngdStartResBody));
            return imResponseResult;
        }
        //重置交互时间和交互次数
        redisTemplate.opsForValue().set(ImTimeKey+sessionId,JSONObject.toJSONString(imRequestServer),20,TimeUnit.MINUTES);
        redisTemplate.opsForValue().set(ImSilentNumKey+sessionId,"0",6,TimeUnit.HOURS);
        logger.info("[sessionId:{}]收到imRequestServer报文为{}",sessionId,imRequestServer);
        //解析IM请求报文
        NGDReqBody ngdReqBody = parseIMChatBody(imRequestServer);
        //请求NGD
        logger.info("[sessionId:{}]请求ngd的报文为{}",sessionId,ngdReqBody);
        NGDResBody ngdResBody = ngdService.query(imRequestServer,ngdReqBody);
            //调用paser解析NGD响应报文
        IMResponseResult imResponseResult =queryParseNgdResult.parseResult(ngdResBody,imRequestServer, dialogueRecord);
        recordService.saveAsyncRecord(dialogueRecord,imRequestServer,imResponseResult,JSONObject.toJSONString(ngdResBody));

        return imResponseResult;
        }catch (Exception e){
            e.printStackTrace();
            logger.error("[sessionId:{}]请求NGD期间出现错误,请求报文:{}",sessionId,imRequestServer,e);
            return new IMResponseResult("1010","query接口请求错误","","");
        }
    }

    @Override
    public IMResponseResult custServerChat(IMRequestServer imRequestServer) {
        String sessionId = imRequestServer.getSessionId();
        if (StringUtils.isEmpty(sessionId)) {
            sessionId = UUID.randomUUID().toString().replace("-", "");
        }
        IMResponseResult imResponseResult = new IMResponseResult();
        QueryJsonStr queryJsonStr = new QueryJsonStr();
        queryJsonStr.setSessionId(sessionId);
        queryJsonStr.setBot(Actions.CUSTOMER.getCode());
        imResponseResult.setReturnCode("200");
        imResponseResult.setReturnMessage("非文本消息");
        imResponseResult.setJsonString(JSONObject.toJSONString(queryJsonStr));
        //不再处理静默策略发送满意度，把下面两个key删除
        redisTemplate.delete(ImSilentNumKey+sessionId);
        redisTemplate.delete(ImTimeKey+sessionId);
        return imResponseResult;
    }

    /**
     *
     * @param imRequestServer
     * @return 解析IM请求报文，整合成NGD标准报文
     */
    private NGDReqBody parseIMChatBody(IMRequestServer imRequestServer){
        NGDReqBody ngdReqBody = new NGDReqBody();
        String channel = imRequestServer.getChannel();
        switch (channel){
            case "0":
                ngdReqBody.setChannel("WeChat");
                break;
            case "1":
                ngdReqBody.setChannel("APP");
                break;
            default:
                ngdReqBody.setChannel(channel);
        }
        ngdReqBody.setCollect(true);
        ngdReqBody.setCollectConversation(true);
        ngdReqBody.setContext(imRequestServer.getContext());
        ngdReqBody.setQueryText(imRequestServer.getQueryText().trim());
        ngdReqBody.setSessionId(imRequestServer.getSessionId());
        return  ngdReqBody;
    }


}
